#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QWidget>
#include <QMessageBox>//消息对话框
#include <QJsonObject>
#include <QJsonParseError>
#include <QMessageBox>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QTimer>
#include <QUrl>

#include "dialog_register.h"
#include "dialog.h"
#include "HttpRequest.h"
#include "qcustomplot.h"


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    m_isLogin = false;
    ui->stackedWidget->setCurrentIndex(7);

    connect(this, &MainWindow::loginRecv, this, &MainWindow::do_loginResponse);

    this->setWindowTitle("MySmartHome");
    // 设置应用程序图标
    this->setWindowIcon(QIcon(":/5"));

    ui->pB_exit->setIcon(QIcon(":/4"));


    m_Model = new QStandardItemModel(0, 1, this);
    m_completer = new QCompleter(m_Model, this);

    ui->le_username->setCompleter(m_completer);

    connect(m_completer, SIGNAL(activated(const QString&)), this, SLOT(onEmailChoosed(const QString&)));
    connect(ui->le_username, SIGNAL(textChanged(const QString&)), this, SLOT(onTextChanged(const QString&)));


    m_http = new HttpRequest(this, "http", "10.11.19.117", "5000");



    //initTableWidget();
    init_curve();

    timer = new QTimer(this);
    connect(timer,&QTimer::timeout,[&](){
        realtimeDataShow();
    });



}

// 复选框状态变化时的槽函数
void MainWindow::onCheckBoxStateChanged(int state)
{
    if (state == Qt::Checked)
    {
        // 复选框被选中，启动定时器
        m_timer->start();
        ui->checkBox_updata->setText("开启自动");
    }
    else
    {
        // 复选框未被选中，停止定时器
        m_timer->stop();
        ui->checkBox_updata->setText("关闭自动");
    }
}

// 定时器超时时的槽函数
void MainWindow::onTimerTimeout()
{
    // 定时器超时时执行的操作
    m_timer->stop();
    qDebug() << "定时器超时";
}

void MainWindow::onEmailChoosed(const QString& email)
{
    ui->le_username->clear();    // 清除已存在的文本更新内容
    ui->le_username->setText(email);
}

void MainWindow::onTextChanged(const QString& str)
{
    if (str.contains("@"))   // 如果已经输入了@符号，我们就停止补全了。因为到了这一步，我们再补全意义也不大了。
    {
        return;
    }
    QStringList strlist;
    strlist << "@163.com" << "@qq.com" << "@gmail.com" << "@hotmail.com" << "@126.com";

    m_Model->removeRows(0, m_Model->rowCount());   // 先清楚已经存在的数据，不然的话每次文本变更都会插入数据，最后出现重复数据
    for (int i = 0; i < strlist.size(); ++i)
    {
        m_Model->insertRow(0);
        m_Model->setData(m_Model->index(0, 0), str + strlist.at(i));
    }
}

MainWindow::~MainWindow()
{
    delete ui;
}




int MainWindow::NormalGetRequest(QString paramer1, QString paramer2)
{
    //生成对应的网络请求
    QNetworkRequest request;
    QString scheme = "http";
    QString serverAddr = "127.0.0.1";
    QString port = "5000";
    QString requestHeader = scheme + QString("://") + serverAddr + QString(":") + port;

    QString fullRequest = requestHeader + QString("/login?username=%1&password=%2").arg(paramer1).arg(paramer2);
    request.setUrl(QUrl(fullRequest));

    //发送Get请求
    QNetworkAccessManager manager;
    QNetworkReply *reply = manager.get(request);
    QEventLoop eventLoop;
    QObject::connect(reply, SIGNAL(finished()),&eventLoop, SLOT(quit()));
    eventLoop.exec(QEventLoop::ExcludeUserInputEvents);

    //对请求的返回异常进行处理
    if(reply->error() != QNetworkReply::NoError)
    {
        return reply->error();
    }

    //解析返回的Json结果
    QByteArray replyData = reply->readAll();
    recvStr = QString(replyData);
    qDebug()<<recvStr;
    QJsonParseError json_error;
    QJsonDocument jsonDoc(QJsonDocument::fromJson(replyData, &json_error));
    if(json_error.error != QJsonParseError::NoError)
    {
        return -1;
    }
    QJsonObject rootObj = jsonDoc.object();

    int codeStr = rootObj.value("code").toInt();
    qDebug()<<codeStr;
    if (codeStr == 200)
    {
        emit loginRecv(true,"success");
        //返回代码为200的时候证明请求成功对包含的结构数据进行处理
        if(rootObj.contains("message"))
        {

        }
        return 0;
    }
    else
    {
        //请求失败对对应的处理

        emit loginRecv(false,"fail");

        return codeStr;
    }

}

void MainWindow::do_loginResponse(bool flag, QString msg)
{
    if(flag)
    {
        QMessageBox::about(this, "提示", QString("登录%1!").arg(msg));
        m_isLogin = true;
    } else {
        QMessageBox::about(this, "提示", QString("登录%1!").arg(msg));
        m_isLogin = false;
    }
}

void MainWindow::do_UserInfoEntered(const QString &username, const QString &password, const QString &email)
{
    qDebug() << "User Info: " << username << password << email;
}

void MainWindow::do_UserInfoListEntered(QStringList info_list)
{
    qDebug() << "User Info List: " << info_list;
}

void MainWindow::on_tB_home_clicked()
{
    ui->stackedWidget->setCurrentIndex(0);
}

void MainWindow::on_tB_control_clicked()
{
//    if(m_isLogin)
        ui->stackedWidget->setCurrentIndex(1);
}

void MainWindow::on_tB_query_clicked()
{
//    if(m_isLogin)
        ui->stackedWidget->setCurrentIndex(2);
}

void MainWindow::on_tB_monitor_clicked()
{
//    if(m_isLogin)
        ui->stackedWidget->setCurrentIndex(3);
}

void MainWindow::on_tB_set_clicked()
{
//    if(m_isLogin)
        ui->stackedWidget->setCurrentIndex(4);
}

void MainWindow::on_action_triggered()
{
    ui->stackedWidget->setCurrentIndex(5);
}

void MainWindow::on_action_2_triggered()
{

}

void MainWindow::on_action_3_triggered()
{
    ui->stackedWidget->setCurrentIndex(6);
}

void MainWindow::on_action_4_triggered()
{

}

void MainWindow::on_action_5_triggered()
{

}

void MainWindow::on_btn_getTH_clicked()
{
    realtimeDataShow();
}

void MainWindow::on_pB_login_clicked()
{
    QString username = ui->le_username->text().trimmed();
    QString password = ui->le_password->text().trimmed();

    if(username.isEmpty() || password.isEmpty())
    {
        QMessageBox::warning(this, "提示", "用户名或密码不能为空");
    } else {
        // 登录
        //m_isLogin = true;

        qDebug() << "GET 返回结果：" <<  NormalGetRequest(username, password);
    }
}

void MainWindow::on_pB_register_clicked()
{
    Dialog_Register *dlg = new Dialog_Register;

    connect(dlg, &Dialog_Register::register_info, this, &MainWindow::do_UserInfoEntered);
    connect(dlg, &Dialog_Register::register_info_list, this, &MainWindow::do_UserInfoListEntered);

    if(dlg->exec()==QDialog::Accepted)
    {

    }
    //QString info(dlg->m_info.at(5));

//    if(dlg->m_info.size() >= 5)
//    {
//        info = dlg->m_info.at(5);
//    }
//    else
//    {
//        info = dlg->m_info.at(0);
//    }

//    QMessageBox::about(this,
//                       "提示",
//                       info);

    qDebug() << dlg->m_info;

}

void MainWindow::do_show_user_info(QStringList user_info)
{
    Q_UNUSED(user_info)

       // 显示消息
       ui->statusbar->showMessage(QString("用户: 芃鸫鸫桁 "));

//       // 添加分割线
//       QFrame* separator = new QFrame();
//       separator->setFrameShape(QFrame::VLine);
//       separator->setFrameShadow(QFrame::Sunken);
//       statusBar->addPermanentWidget(separator);

//       // 显示消息
//       statusBar->showMessage(QString("用户ID: %1 用户名: %2  状态: %3.").arg(user_info.at(0)).arg(user_info.at(1)).arg(user_info.at(2)));

//       // 添加分割线
//       QFrame* separator_2 = new QFrame();
//       separator_2->setFrameShape(QFrame::VLine);
//       separator_2->setFrameShadow(QFrame::Sunken);
//       statusBar->addPermanentWidget(separator_2);

//       // 显示消息
//       statusBar->showMessage(QString("用户ID: %1\t用户名: %2\t状态: %3.").arg(user_info.at(0)).arg(user_info.at(1)).arg(user_info.at(2)));
}

void MainWindow::on_tb_query_data_clicked()
{
    QMap<QString, QString> map_post, map_get;


    // 发送GET请求
    m_http->NormalGetRequest("/home/sensor_data_1_1_3", map_get);

    if(200 == HttpRequest::m_map_get.value("code").toInt())
    {
        ui->dbsb_temperature->setValue(HttpRequest::m_map_get.value("data").toMap().value("Temp").toDouble());
        ui->dbsb_humidity->setValue(HttpRequest::m_map_get.value("data").toMap().value("humidity").toDouble());
        ui->dbsb_smoke->setValue(HttpRequest::m_map_get.value("data").toMap().value("smoke").toDouble());
    }
    // 发送GET请求
    m_http->NormalGetRequest("/device/get_status", map_get);

    if(200 == HttpRequest::m_map_get.value("code").toInt())
    {
        if("ON" == HttpRequest::m_map_get.value("data").toMap().value("alarm").toString())
        {
            ui->pb_alarm->setText("开");
            m_alarm_flag = true;
        } else {
            ui->pb_alarm->setText("关");
            m_alarm_flag = false;
        }

        if("ON" == HttpRequest::m_map_get.value("data").toMap().value("led").toString())
        {
            ui->pb_led->setText("开");
            m_led_flag = true;
        } else {
            ui->pb_led->setText("关");
            m_led_flag = false;
        }

        if("ON" == HttpRequest::m_map_get.value("data").toMap().value("fan").toString())
        {
            ui->pb_fan->setText("开");
            m_fan_flag = true;

        } else {
            ui->pb_fan->setText("关");
            m_fan_flag = false;
        }

        if("ON" == HttpRequest::m_map_get.value("data").toMap().value("lock").toString())
        {
            ui->pb_lock->setText("开");
            m_lock_flag = true;
        } else {
            ui->pb_lock->setText("关");
            m_lock_flag = false;
        }
    }
}

void MainWindow::on_pb_alarm_clicked()
{
    QString url = "/control_alarm/";

    if(m_alarm_flag == false)
    {
        url += "1";
        m_alarm_flag = true;
        ui->pb_alarm->setText("开");
    } else {
        url += "0";
        m_alarm_flag = false;
        ui->pb_alarm->setText("关");
    }

    QMap<QString, QString> map_get;
    // 发送GET请求
    m_http->NormalGetRequest(url, map_get);
}

void MainWindow::on_pb_led_clicked()
{
    QString url = "/control_led/";

    if(m_led_flag == false)
    {
        url += "1";
        m_led_flag = true;
        ui->pb_led->setText("开");
    } else {
        url += "0";
        m_led_flag = false;
        ui->pb_led->setText("关");
    }

    QMap<QString, QString> map_get;
    // 发送GET请求
    m_http->NormalGetRequest(url, map_get);
}

void MainWindow::on_pb_fan_clicked()
{

    QString url = "/control_fan/";

    if(m_fan_flag == false)
    {
        url += "1";
        m_fan_flag = true;
        ui->pb_fan->setText("开");
    } else {
        url += "0";
        m_fan_flag = false;
        ui->pb_fan->setText("关");
    }

    QMap<QString, QString> map_get;
    // 发送GET请求
    m_http->NormalGetRequest(url, map_get);

}

void MainWindow::on_pb_lock_clicked()
{

    QString url = "/control_lock/";

    if(m_lock_flag == false)
    {
        url += "1";
        m_lock_flag = true;
        ui->pb_lock->setText("开");
    } else {
        url += "0";
        m_lock_flag = false;
        ui->pb_lock->setText("关");
    }

    QMap<QString, QString> map_get;
    // 发送GET请求
    m_http->NormalGetRequest(url, map_get);

}


/*曲线显示*/
void MainWindow::init_curve()    //初始化的时候做，建议只做一次，如果重复做，需要提前清空曲线的一些属性，不然会导致图例越来越多，轴重复等问题
{
    ui->customPlot_humidy->addGraph(); //增加一条曲线，从graph(0)开始
    ui->customPlot_humidy->graph(0)->setPen(QPen(Qt::blue));    //曲线线条颜色蓝色
    ui->customPlot_humidy->graph(0)->setName("温度");
    ui->customPlot_humidy->yAxis->setRange(10,100);
    ui->customPlot_humidy->graph(0)->rescaleValueAxis(true, true);//y的极大值显示出来，此时y的极大值在最大范围处，顶到曲线最上方
    ui->customPlot_humidy->graph(0)->rescaleAxes();    //极大值调整向下l、
    ui->customPlot_humidy->addGraph(); // red line
    ui->customPlot_humidy->graph(1)->setPen(QPen(Qt::red));
    ui->customPlot_humidy->graph(1)->setName("湿度");
    ui->customPlot_humidy->addGraph(); //增加一条曲线，从graph(2)开始
    ui->customPlot_humidy->graph(2)->setPen(QPen(Qt::green));    //曲线线条颜色绿色
    ui->customPlot_humidy->graph(2)->setName("烟雾浓度");
    ui->customPlot_humidy->axisRect()->setupFullAxesBox();
   ui->customPlot_humidy->legend->setVisible(true);        //图例可见，既曲线一与曲线二的图例自动生成，位置也可以调整，后面说怎么调
    //设置时间格式
     QSharedPointer<QCPAxisTickerDateTime> timer(new QCPAxisTickerDateTime);
    timer->setDateTimeFormat("h:mm:ss");
    //设置时间轴 一共几格
    timer->setTickCount(10);
    //设置label 旋转35° 横着显示可能显示不全
    ui->customPlot_humidy->xAxis->setTickLabelRotation(35);
    ui->customPlot_humidy->xAxis->setTicker(timer);
    ui->customPlot_humidy->graph(0)->rescaleValueAxis(true, true);
    ui->customPlot_humidy->graph(0)->rescaleAxes();
    timer->setTickStepStrategy(QCPAxisTicker::tssMeetTickCount);

    //生成游标
    tracer = new QCPItemTracer(ui->customPlot_humidy); //生成游标

    tracer->setPen(QPen(Qt::red));//圆圈轮廓颜色
    tracer->setBrush(QBrush(Qt::red));//圆圈圈内颜色
    tracer->setStyle(QCPItemTracer::tsCircle);//圆圈
    tracer->setSize(5);//设置大小

    //游标说明
    tracerLabel = new QCPItemText(ui->customPlot_humidy); //生成游标说明
    tracerLabel->setLayer("overlay");//设置图层为overlay，因为需要频繁刷新
    tracerLabel->setPen(QPen(Qt::white));//设置游标说明颜色
    tracerLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop);//左上
    tracerLabel->position->setParentAnchor(tracer->position);//将游标说明锚固在tracer位置处，实现自动跟随

    //信号-槽连接语句
    connect(ui->customPlot_humidy,&QCustomPlot::mouseMove,this,&MainWindow::mouseMove);

}

void MainWindow::mouseMove(QMouseEvent *e)
{
    //获得鼠标位置处对应的横坐标数据x
    double x = ui->customPlot_humidy->xAxis->pixelToCoord(e->pos().x());
    tracer->setGraph(ui->customPlot_humidy->graph(0)); //将游标和该曲线图层想连接
    tracer->setGraphKey(x); //将游标横坐标设置成刚获得的横坐标数据x
    tracer->setInterpolating(true); //游标的纵坐标可以通过曲线数据线性插值自动获得
    tracer->updatePosition(); //使得刚设置游标的横纵坐标位置生效
    //更新游标说明的内容
    double xValue = tracer->position->key();
    double yValue = tracer->position->value();
    QDateTime time2 = QDateTime::fromTime_t(xValue);
    tracerLabel->setText(QString("x = %1 y = %2").arg(time2.toString("hh:mm:ss")).arg(yValue));
    ui->customPlot_humidy->replot(QCustomPlot::rpQueuedReplot); //重绘
}

double start_key = -1;
int key_count ;
void MainWindow::realtimeDataShow()    //实时更新曲线数据
{
    double key = QDateTime::currentDateTime().toTime_t();
    static double value0 = 0;
    static double value1 = 0;
    static double value2 = 0;

    QMap<QString, QString> map_get;

    m_http->NormalGetRequest("/home/sensor_data_1_1_3", map_get);
    qDebug() << "<------------获取更新数据------------>";
    //key的单位是秒
    if(200 == HttpRequest::m_map_get.value("code").toInt())
    {
        value0 = HttpRequest::m_map_get.value("data").toMap().value("Temp").toDouble();
        value1 = HttpRequest::m_map_get.value("data").toMap().value("humidity").toDouble();
        value2 = HttpRequest::m_map_get.value("data").toMap().value("smoke").toDouble();
        qDebug()<<"----> 温度：" << value0 << "湿度：" << value1 << "烟雾浓度：" << value2;
        ui->dbsb_temp->setValue(value0);
        ui->dbsp_hum->setValue(value1);
        ui->dbsp_smoke->setValue(value2);
    }

    //设置坐标轴
    if(start_key == -1 )
    {
        start_key = key;
        key_count = 0;
    }
    ++key_count;
    ui->customPlot_humidy->xAxis->setRange(start_key,key_count > 10 ? key_count: 10,Qt::AlignLeft);
    ui->customPlot_humidy->xAxis->setRange(key_count < 10?  start_key :key -10,10,Qt::AlignLeft);

    ui->customPlot_humidy->graph(0)->addData(key, value0);//添加温度数据到曲线0
    ui->customPlot_humidy->graph(1)->addData(key, value1);//添加湿度数据到曲线1
    ui->customPlot_humidy->graph(2)->addData(key, value2);//添加烟雾浓度数据到曲线2
    ui->customPlot_humidy->replot(QCustomPlot::rpQueuedReplot);    //重画实现实时曲线刷新

}


void MainWindow::timerOut()
{
   realtimeDataShow();
}

void MainWindow::on_btn_getTH_allTime_clicked()
{
    if(ui->btn_getTH_allTime->text()=="实时跟踪")
    {
        ui->btn_getTH_allTime->setText("停止跟踪");
        timer->start(1000);
    }
    else if(ui->btn_getTH_allTime->text()=="停止跟踪")
    {
        ui->btn_getTH_allTime->setText("实时跟踪");
        timer->stop();
    }
}

void MainWindow::handleLoginCompleted(QString username)
{
    ui->statusbar->showMessage(QString("用户: %1 ").arg(username));
    ui->le_user_name->setText(username);

    QMap<QString, QString> map;

    map.insert("user_name", username);

    // 发送POST请求
    m_http->NormalPostRequest("/user/get", map);

    if(200 == HttpRequest::m_map_post.value("code").toInt())
    {
        // 填写信息
        ui->le_user_id->setText(HttpRequest::m_map_post.value("data").toMap().value("user_id").toString());
        ui->le_user_home->setText(HttpRequest::m_map_post.value("data").toMap().value("home_name").toString());

        map.clear();
        // 发送POST请求
        m_http->NormalGetRequest("/home/sensor_data_1_1_3", map);

        if(200 == HttpRequest::m_map_get.value("code").toInt())
        {
            ui->dbsb_temperature->setValue(HttpRequest::m_map_get.value("data").toMap().value("Temp").toDouble());
            ui->dbsb_humidity->setValue(HttpRequest::m_map_get.value("data").toMap().value("humidity").toDouble());
            ui->dbsb_smoke->setValue(HttpRequest::m_map_get.value("data").toMap().value("smoke").toDouble());
        }
        m_timer = new QTimer(this);

        connect(m_timer, &QTimer::timeout, this, &MainWindow::on_tb_query_data_clicked);
        // 连接复选框的状态变化信号到槽函数
        connect(ui->checkBox_updata, &QCheckBox::stateChanged, this, &MainWindow::onCheckBoxStateChanged);

        // 设置定时器间隔，单位为毫秒
        m_timer->setInterval(1000); // 1秒

        if(ui->checkBox_updata->isChecked())
        {
            m_timer->start(1000);
            ui->checkBox_updata->setText("开启自动");
        }
    }
}


